//
// Created by qsy on 2023/7/20. //STM32 模拟SPI
//
#include "SCA100T.h"
#include "spi.h"
#include "math.h"

uint16_t AngleSensorbuf[] = {};  //缓冲区 倾角数据处理

GPIO_InitTypeDef GPIO_handel;  //初始化引脚的句柄
void delay_us(uint16_t time)
{
    uint16_t i=0;
    while(time--)
    {
        i=10;  //
        while(i--) ;
    }
}

//void An_Tran_IOConfigure(void)  配置MISO、MOIS、SCK引脚 这里略去，初始化在spi中
void An_Tran_IOConfigure(void)
{
//    MX_SPI1_Init(); //初始化spi SPI中包含 MOSI、MISO、SCK、NSS

    GPIO_handel.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_handel.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7; //MOSI,SCK,CS
    GPIO_handel.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA,&GPIO_handel);

    GPIO_handel.Pin = GPIO_PIN_6;                       //MISO
    GPIO_handel.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(GPIOA,&GPIO_handel);
}
//写入一个数据指令
void An_Tran_WR_Byte(uint8_t command)
{
    uint8_t it=0,i=0;
    CSB_CLR;
    it=command;

    for(i=0;i<8;i++)
    {
        SCK_CLR;
        delay_us(2);
        if(it&0x80)
        {
            MOSI_SET;
        }
        else
        {
            MOSI_CLR;
        }
        SCK_SET;
        it=(it<<1);
        delay_us(2);
    }
    CSB_SET;
    SCK_CLR;
    delay_us(150);
}

//初始化
void An_Tran_Init(void)
{
    An_Tran_IOConfigure( );
    An_Tran_WR_Byte(STX);  //自检
    HAL_Delay(1);
    An_Tran_WR_Byte(STY);  //自检
    HAL_Delay(1);
    An_Tran_WR_Byte(MEAS); //工作在测量模式
    HAL_Delay(1);
}

//读取一个数据
uint16_t An_Tran_Read_Byte(uint8_t command)
{
    uint8_t i=0;
    int16_t indata=0;


    CSB_CLR;
    for(i=0;i<8;i++)   // 发送命令
    {
        SCK_CLR;
        delay_us(1);
        if(command&0x80)
        {
            MOSI_SET;
        }
        else
        {
            MOSI_CLR;
        }
        SCK_SET;
        command=(command<<1);
        delay_us(1);
    }
    SCK_CLR;
    indata=0;
    for(i=0; i<11; i++)  //11位数据 润色
    {
        SCK_SET;
        indata=indata<<1;
        if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)!=0)  // 读取输入值  这里PAin(6) 不懂，应该是读取PA6的状态 可能后续需要改一下
        {
            indata=indata+1;
        }
        SCK_CLR;
        delay_us(1);
    }
    CSB_SET;
    delay_us(50);
    return(indata);
}
//选择排序算法
void selectSort(int16_t arr[],int len)
{
    int i = 0;
    int k = 0;//保存无序区第一个元素下标，方便比较
    //一趟确定一个有序区元素，最后一次不用确定，总共len-1次
    for (i = 0; i < len - 1; i++)
    {
        k = i;
        int j = 0;
        //确定无序区最小元素下标
        for (j = i + 1; j < len; j++)
        {
            if (arr[j] < arr[k])
            {
                k = j;
            }
        }
        //如果无序区第一个元素为最小，则没有必要交换
        if (i != k)
        {
            int tmp = arr[k];
            arr[k] = arr[i];
            arr[i] = tmp;
        }
    }
}

//倾角数据处理
uint16_t AngularDataProcess(uint8_t Channel)//倾角数据处理
{
    uint16_t themp;
    uint8_t  i,j;
    j = 0;

    for(i=0;i<100;i++)//循环读数
    {
        themp = An_Tran_Read_Byte(Channel);
        if((themp >= 1)&&(themp <= 2046))           //有效数据 205---1843; 扩大范围，加入无效数据、后面再处理
        {
            AngleSensorbuf[j]=themp;
            j++;//有效点数量
        }
    }
    if(j>0)
    {
        selectSort(AngleSensorbuf,j);
        printf("AngleSensorbuf:%d\r\n",AngleSensorbuf[j/2]);
        return AngleSensorbuf[j/2];
    }
}

//如果读取的数据小于1024则代表右倾即左摆，大于1024则代表左倾即右摆 ，计算方法为：角度=arcsin【（输出的数据-1024）/819】
double AngularConvert(uint8_t Channel)	  //转换角度函数，45.45度为4545，最高位为1为右倾也即左摆
{
    double tempbuf=0;
    double tempbuf1=0;
    double tempbuf2=0;
    int16_t rawbuf;

//    An_Tran_WR_Byte(0x0E); //工作在自检模式
    An_Tran_WR_Byte(0x00); //工作在测量模式
    rawbuf = AngularDataProcess(Channel);

    tempbuf1=(double)(rawbuf);
    if(tempbuf1<1024)
    {
        tempbuf2=(asin((1024-tempbuf1)/SCA100T_D01_Resolution))*180/3.1415926; //SCA100T_D01_Resolution 1638
        tempbuf=tempbuf2;
    }
    else
    {
        tempbuf2=(asin((tempbuf1-1024)/SCA100T_D01_Resolution))*180/3.1415926; //SCA100T_D01_Resolution 1638
        tempbuf=(-1)*tempbuf2;
    }
    if (tempbuf>30){
        return 30;
    }
    if (tempbuf<-30){
        return -30;
    }
    return  tempbuf;


}

//获取X、Y倾角并打印
void SCA100T_task(void)
{
    double Xtemp;
    double Ytemp;

    Xtemp = AngularConvert(RDAX);
    Ytemp = AngularConvert(RDAY);

    printf("X倾角:%f\r\n", Xtemp);
    printf("Y倾角:%f\r\n", Ytemp);
    printf("\r\n");

}


